
import { _decorator, Component, Node ,log ,TiledMap ,Vec3 ,tween ,UITransform} from 'cc';

import { ClientEvent } from '../framework/clientEvent';
import { Constant } from '../framework/constant';
import {Channel, GameState, Player} from "./GameState";
import {PlayerLogic} from "./playerLogic";
import {PropLogic} from "./propLogic";
import {MgobeUtil} from "./mgobeUtil";
import {MapUtil} from "./mapUtil";
import {Util} from "../framework/util";

const { ccclass, property } = _decorator;

/**
 * Predefined variables
 * Name = LogicManager
 * DateTime = Sat Dec 18 2021 14:49:35 GMT+0800 (中国标准时间)
 * Author = yly1234560
 * FileBasename = logicManager.ts
 * FileBasenameNoExtension = logicManager
 * URL = db://assets/scripts/core/logicManager.ts
 * ManualUrl = https://docs.cocos.com/creator/3.3/manual/zh/
 *
 */
 
@ccclass('LogicManager')
export class LogicManager extends Component {
    @property(PlayerLogic)
    public playerLogic: PlayerLogic = null!;

    @property(PropLogic)
    public propLogic: PropLogic = null!;

    public isGameStart: boolean = false;
    public currentGameState: GameState = {} as GameState;

    // public get scriptDisplayManager() {
    //     return find("display")?.getComponent(DisplayManager) as DisplayManager;
    // }

    private _arrayGameState: { [index: number]: GameState } = [];
    private _currentPlayerId: string = "";
    private _startGameTime: number = 0;
    private _isGameStop: boolean = false;


    // 当前选中的棋子
    // private _selectPiece: string = '';
    private _selectPiece:Node = null;

    // 是否可行动 暂时不考虑掉线重连，如果需要重连需要把该属性写入 room信息
    private _isAction: boolean = false;
    // 当前阵营 0蓝色 1红色
    private _camp: number = 0;

    start() {
        // this.playerLogic.init(this);
        // this.propLogic.init(this);
    }

    onEnable() {
        ClientEvent.on(Constant.EVENT_NAME.ON_GET_ROOM_INFO, this._onGetRoomInfo, this);
        ClientEvent.on(Constant.EVENT_NAME.ON_START_FRAME_SYNC, this._onStartFrameSync, this);
        // ClientEvent.on(Constant.EVENT_NAME.ON_STOP_FRAME_SYNC, this._onStopFrameSync, this);
        ClientEvent.on(Constant.EVENT_NAME.ON_RECV_SYNC, this._onRecvSync, this);
        ClientEvent.on(Constant.EVENT_NAME.ON_DEBUG_GAME_STATE, this._printAction, this);

        ClientEvent.on(Constant.EVENT_NAME.ON_RECV_FROM_CLIENT, this._onRecvFromClient, this);
        ClientEvent.on(Constant.EVENT_NAME.ON_ROUND_TIME_OUT, this._sendTimeOut, this);
    }

    onDisable() {
        ClientEvent.off(Constant.EVENT_NAME.ON_GET_ROOM_INFO, this._onGetRoomInfo, this);
        ClientEvent.off(Constant.EVENT_NAME.ON_START_FRAME_SYNC, this._onStartFrameSync, this);
        // ClientEvent.off(Constant.EVENT_NAME.ON_STOP_FRAME_SYNC, this._onStopFrameSync, this);
        ClientEvent.off(Constant.EVENT_NAME.ON_RECV_SYNC, this._onRecvSync, this);
        ClientEvent.off(Constant.EVENT_NAME.ON_DEBUG_GAME_STATE, this._printAction, this);

        ClientEvent.off(Constant.EVENT_NAME.ON_RECV_FROM_CLIENT, this._onRecvFromClient, this);
        ClientEvent.off(Constant.EVENT_NAME.ON_ROUND_TIME_OUT, this._sendTimeOut, this);
    }

    /**
     * 设置第0帧数据
     */
    public setDefaultGameState() {
        this._arrayGameState = [];
        // this.playerLogic.reset();
        // this.propLogic.reset();
        this.currentGameState.id = 0;
        // this.currentGameState.props = this.propLogic.initProps();
        this.currentGameState.players = this._initPlayer();
        this.currentGameState.frameTime = Date.now();
        this.currentGameState.createHammerTime = Number.MAX_SAFE_INTEGER;
        this.isGameStart = false;
        this._arrayGameState[0] = this.currentGameState;
    }

    public _initPlayer() {
        let players: Array<Player>= [];
        for(let i: number = 0; i < Constant.MAX_PLAYER; i++) {
            let player: Player = {} as Player;
            // let pos: Vec3 = new Vec3(-27, 0, -21);
            // let eulerAngles: Vec3 = new Vec3(0, 180, 0);
            // switch (i) {
            //     case 0:
            //         break;
            //     case 1:
            //         pos = new Vec3(23, 0, 18);
            //         eulerAngles = new Vec3(0, 0, 0);
            //         break;
            //     case 2:
            //         pos = new Vec3(23, 0, -21);
            //         eulerAngles = new Vec3(0, 180, 0);
            //         break;
            //     case 3:
            //         pos = new Vec3(-27, 0, 18);
            //         eulerAngles = new Vec3(0, 0, 0);
            //         break;
            // }
            player.id = i;
            // player.position = pos;
            // player.eulerAngles = eulerAngles;
            player.score = 0;
            player.hammerCount = 0;
            player.dizzyTime = 0;
            player.attackPos = null;
            player.attackId = -1;
            player.isScoreLead = false;
            player.camp = -1;
            players[i] = player;
            // let node = PoolManager.instance.getNode(this.virtualPlayerPrefab, this.node);
            // node.setWorldPosition(pos);
            // node.eulerAngles = eulerAngles;
            // this._dicPlayers[i] = node;
        }
        return players;
    }

    /**
     * 收到房间信息
     */
    private _onGetRoomInfo(roomInfo: MGOBE.types.RoomInfo, playerId: string) {
        log("收到房间信息_onGetRoomInfo:"+roomInfo+"*****"+playerId);


        this._currentPlayerId = playerId;
        let readyState: boolean = false;
        let playerList: MGOBE.types.PlayerInfo[] = roomInfo.playerList;
        let players: Array<Player> = this.currentGameState.players;
        let unconnectState: boolean = false;
        playerList.forEach((value: MGOBE.types.PlayerInfo, index: number) => {
            let player: Player = players[index];
            if (!player.channel) player.channel = {} as Channel;
            player.channel.openId = value.id;
            player.channel.name = value.name;
            player.channel.state = value.customPlayerStatus;
            player.channel.delayTime = 0;
            if (roomInfo.frameSyncState === Constant.FRAME_SYNC_STATE.STOP && value.customPlayerStatus === Constant.CUSTOM_PLAYER_STATUS.GAME) {
                player.channel.state = Constant.CUSTOM_PLAYER_STATUS.CONNECTED;
            }

            if (value.commonNetworkState === MGOBE.types.NetworkState.COMMON_OFFLINE || value.commonNetworkState === MGOBE.types.NetworkState.RELAY_OFFLINE) {
                player.channel.state = Constant.CUSTOM_PLAYER_STATUS.UNCONNECTED;
                unconnectState = true;
            }
            if (this._currentPlayerId === value.id) readyState = (player.channel.state === Constant.CUSTOM_PLAYER_STATUS.READY || player.channel.state === Constant.CUSTOM_PLAYER_STATUS.GAME);

            // yly 添加阵营
            if (this._currentPlayerId === value.id) {
                // if(player.camp==-1){
                    player.camp = index;
                    this._camp = index;
                    // 如果是0 代表蓝色 蓝色先走 暂时先固定 蓝色先走
                    if(index == 0){
                        this._isAction = true;
                    }
                // }
                log("******this._currentPlayerId === value.id******",this._currentPlayerId );
            }
            player.channel.headUrl = value.customProfile;
        });



        if (roomInfo.frameSyncState === Constant.FRAME_SYNC_STATE.START && !this.isGameStart) {
            if (unconnectState) {
                MgobeUtil.instance.stopFrameSync();
            } else {
                // console.log("*****ON_GAME_START****");
                // console.log("*****ON_GAME_START****");
                // console.log("*****ON_GAME_START****");
                // console.log("*****ON_GAME_START****");



                this._onStartFrameSync(roomInfo.startGameTime);
                ClientEvent.dispatchEvent(Constant.EVENT_NAME.ON_GAME_START);
            }
            return;
        } else if (roomInfo.frameSyncState === Constant.FRAME_SYNC_STATE.STOP && this.isGameStart) {
            this._onStopFrameSync();
            MgobeUtil.instance.changeCustomPlayerStatus(Constant.CUSTOM_PLAYER_STATUS.CONNECTED);
        }
        log("收到房间信息_onGetRoomInfo end *****");
        ClientEvent.dispatchEvent(Constant.EVENT_NAME.ON_GET_ROOM_ID, roomInfo.id, readyState);
    }

    /**
     * 开始帧同步操作
     */
    private _onStartFrameSync(startGameTime: number) {

        log("开始帧同步操作 _onStartFrameSync:"+startGameTime);
        this.isGameStart = true;
        this._isGameStop = false;
        this._startGameTime = startGameTime;
        this._arrayGameState[0] = Util.clone(this.currentGameState);

        // let gameState: GameState = this.currentGameState;
        // let players: Array<Player> = gameState.players;
        // this.playerLogic.updatePlayerNode(players);
    }

    /**
     * 结束帧同步操作
     */
    private _onStopFrameSync() {
        log("结束帧同步操作 _onStopFrameSync:");
        this.isGameStart = false;
        let players: Array<Player> = this.currentGameState.players;
        let result = players.filter((value: Player) => {
            return value.channel && value.channel.openId === this._currentPlayerId;
        });
        if (!result.length) return;

        ClientEvent.dispatchEvent(Constant.EVENT_NAME.ON_GAME_END);
    }

    /**
     * 收到帧数据回调
     * @param frame 帧数据
     */
    private _onRecvSync(frame: Array<MGOBE.types.Frame>) {
        log("收到帧数据回调 _onRecvSync:"+frame);
        // frame.forEach((value: MGOBE.types.Frame) => {
        //     if (!this._arrayGameState[value.id - 1]) return;
        //     this.currentGameState = this._handleGameState(this._arrayGameState[value.id - 1]);
        //     let players: Array<Player> = this.currentGameState.players;
        //     players.forEach((value: Player) => {
        //         value.attackPos = null;
        //     });
        //
        //     this.propLogic.removeOverProp(this.currentGameState.props.length);
        //     this._handleFrame(value);
        //     this._arrayGameState[value.id] = Util.clone(this.currentGameState);
        //     //表现层的update使用逻辑层的
        //     this.scriptDisplayManager.updateState(1 / Constant.GAME_FRAME);
        // });


        frame.forEach((value: MGOBE.types.Frame) => {
            if (!this._arrayGameState[value.id - 1]) return;


            this._handleFrame(value);
        });
    }

    /**
     * 处理帧数据
     * @param frame 帧数据
     */
    private _handleFrame(frame: MGOBE.types.Frame) {
        log("处理帧数据 _handleFrame:"+frame);

        // frame.data

    }

    /**
     * 处理玩家操作
     * @param frame 帧数据
     */
    private _handleAction(frame: MGOBE.types.FrameItem) {
        log("处理玩家操作 _handleAction:"+frame);
        // let playerId: string = frame.playerId;
        // let players: Array<Player> = this.currentGameState.players;
        // let result = players.filter((value: Player) => {
        //     return value.channel && value.channel.openId === playerId;
        // });
        // if (!result.length) return;
        // let data: { A: number, V: number } = frame.data as { A: number, V: number };
        // switch (data.A) {
        //     case Constant.ACTION.MOVE:
        //         let angle: number = data.V as number;
        //         let radian: number = angle * Math.PI / 180;
        //         let horizontal: number = Math.round(Math.cos(radian) * 1);
        //         let vertical: number = Math.round(Math.sin(radian) * 1);
        //         this.playerLogic.handleMove(result[0], horizontal, vertical);
        //         break;
        //     case Constant.ACTION.STOP_MOVE:
        //         this.playerLogic.handleMove(result[0], 0, 0);
        //         break;
        //     case Constant.ACTION.HEART_BEAT:
        //         result[0].channel.delayTime = data.V as number;
        //     case Constant.ACTION.HIT:
        //         this.playerLogic.checkAttack(result[0]);
        //         break;
        // }
    }

    /**
     * 使用clone Vec3 会变成object 需要转为Vec3
     * @param gameState
     * @returns
     */
    // private _handleGameState(gameState: GameState) {
        // // let gameState: GameState = JSON.parse(state);
        // gameState.players.forEach((value: any) => {
        //     //安卓平台vec3 会转成_array: {0: 13.304662704467773, 1: 0, 2: -5.162149429321289}
        //     if (value.position._array) {
        //         v3_1.set(value.position._array[0], value.position._array[1], value.position._array[2]);
        //     } else {
        //         v3_1.set(value.position.x, value.position.y, value.position.z);
        //     }
        //     value.position = v3_1.clone();
        //
        //     if (value.eulerAngles._array) {
        //         v3_1.set(value.eulerAngles._array[0], value.eulerAngles._array[1], value.eulerAngles._array[2]);
        //     } else {
        //         v3_1.set(value.eulerAngles.x, value.eulerAngles.y, value.eulerAngles.z);
        //     }
        //     value.eulerAngles = v3_1.clone();
        //
        //     if (value.attackPos) {
        //         if (value.attackPos._array) {
        //             v3_1.set(value.attackPos._array[0], value.attackPos._array[1], value.attackPos._array[2]);
        //         } else {
        //             v3_1.set(value.attackPos.x, value.attackPos.y, value.attackPos.z);
        //         }
        //         value.attackPos = v3_1.clone();
        //     }
        // });
        // gameState.props.forEach((value: any) => {
        //     if (value.position._array) {
        //         v3_1.set(value.position._array[0], value.position._array[1], value.position._array[2]);
        //     } else {
        //         v3_1.set(value.position.x, value.position.y, value.position.z);
        //     }
        //     value.position = v3_1.clone();
        //
        //     if (value.dropPosition) {
        //         if (value.dropPosition._array) {
        //             v3_1.set(value.dropPosition._array[0], value.dropPosition._array[1], value.dropPosition._array[2]);
        //         } else {
        //             v3_1.set(value.dropPosition.x, value.dropPosition.y, value.dropPosition.z);
        //         }
        //         value.dropPosition = v3_1.clone();
        //     }
        // });
        // return gameState;
    // }

    private _printAction() {
        // let arr: any[] = [];
        // let keys: string[] = Object.keys(this._arrayGameState);
        // keys.forEach((value: string) => {
        //     let gameState: GameState = this._arrayGameState[parseInt(value)];
        //     if (gameState.isActionFrame) {
        //         arr.push(gameState);
        //     }
        // });
        // console.log(arr);
    }

    /**
     * 设置分数领先的玩家
     */
    private _checkPlayerScoreLead() {
        // let maxScoreIdx = -1;
        // let maxScore: number = 0;
        //
        // for (let idx in this.currentGameState.players) {
        //     let player: Player = this.currentGameState.players[idx];
        //     if (player.channel) {
        //         if (maxScore < player.score) {
        //             maxScore = player.score;
        //         }
        //     }
        // }
        //
        // //初始分数都为零则不设置谁领先
        // if (maxScore === 0) {
        //     return;
        // }
        //
        // //筛选出分数相同的玩家
        // let arrMaxScorePlayer = this.currentGameState.players.filter((player: Player) => {
        //     return player.score === maxScore;
        // })
        //
        // // 玩家分数得超越另一位才能标记分数领先
        // for (let index = 0; index < arrMaxScorePlayer.length; index++) {
        //     const player = arrMaxScorePlayer[index];
        //     if (player.isScoreLead) {
        //         maxScoreIdx = player.id;
        //         break;
        //     }
        // }
        //
        // if (maxScoreIdx === -1) {
        //     maxScoreIdx = arrMaxScorePlayer[0].id;
        // }
        //
        // this.currentGameState.players.forEach((player: Player) => {
        //     player.isScoreLead = player.id === maxScoreIdx;
        // })
    }



    // 棋子点击事件
    public piecesOnClick(event, customEventData){
        console.log("**eventeventevent**");

        if(!this._isAction){
            return;
        }


        let node = event.target as Node;

        if(this._selectPiece !=null && node.name != this._selectPiece.name){
            // 清掉其他
            this.clearFootAndFight();
        }

        this._selectPiece = node;
        // 显示脚印
        this._showFoot(node);

        // 显示可以攻击
        this._showFight(node);

    }


    // 可移动路线
    private _showFoot(node:Node){


        // 上
        let position = this._isNotMove("up",node);
        let foot = node.getChildByName("up") as Node;
        if(position!=null){
            foot.setPosition(position[0],position[1]);
            foot.active = true;
        }else{
            foot.active = false;
        }

        // 下
        position = this._isNotMove("down",node);
        foot = node.getChildByName("down") as Node;
        if(position!=null){
            foot.setPosition(position[0],position[1]);
            foot.active = true;
        }else{
            foot.active = false;
        }

        position = this._isNotMove("left",node);
        foot = node.getChildByName("left") as Node;
        // 左
        if(position!=null){
            foot.setPosition(position[0],position[1]);
            foot.active = true;
        }else{
            foot.active = false;
        }
        // 右
        position = this._isNotMove("right",node);
        foot = node.getChildByName("right") as Node;
        if(position!=null){
            foot.setPosition(position[0],position[1]);
            foot.active = true;
        }else{
            foot.active = false;
        }
    }

    // 检查河流中是否有老鼠
    private _checkRiverHasMouse(node:Node,type:string):boolean{
        // 只有老鼠可以下水，只要有棋子就是老鼠
        for (let i = 1; i <= 3; i++) {
            if(type == "up"){
                if(MapUtil.instance.mapPieces.has(MapUtil.instance.getKey(node.position.x,node.position.y+148*i))){
                    return true;
                }
            }
            if(type == "down"){
                if(MapUtil.instance.mapPieces.has(MapUtil.instance.getKey(node.position.x,node.position.y-148*i))){
                    return true;
                }
            }
        }

        for (let i = 1; i <= 2; i++) {
            if(type == "left"){
                if(MapUtil.instance.mapPieces.has(MapUtil.instance.getKey(node.position.x-148*i,node.position.y))){
                    return true;
                }
            }
            if(type == "right"){
                if(MapUtil.instance.mapPieces.has(MapUtil.instance.getKey(node.position.x+148*i,node.position.y))){
                    return true;
                }
            }
        }
        return false;
    }


    // 是否可移动
    private _isNotMove(type:string,node:Node){

        // 节点坐标
        let pos = this._willMove(type,node.position.x,node.position.y,0);
        if(pos[0]<-518 || pos[0]>518){
            return null;
        }
        if(pos[1]<-666 || pos[1]>666){
            return null;
        }
        // 穿越河流坐标
        let pos_ = this._willMove(type,node.position.x,node.position.y,1);

        let pos1 = this._willMove(type,0,0,0);
        let pos2 = this._willMove(type,0,0,1);


        // 当前阵营
        let camp = node.name.substr(0,1);
        // 是否是兽穴
        let w = MapUtil.instance.mapBen.has(MapUtil.instance.getKey(pos[0],pos[1]));
        if("r" == camp  && pos[1]<0 && w){
            return pos1;
        }
        if("r" == camp  && pos[1]>0 && w){
            return null;
        }
        if("b" == camp  && pos[1]>0 && w){
            return pos1;
        }
        if("b" == camp  && pos[1]<0 && w){
            return null;
        }


        // 是老鼠时可任意行动
        if(!(node.name.indexOf("_mouse") == -1)){
            // 将行进路线无棋子时
            if(!MapUtil.instance.mapPieces.has(MapUtil.instance.getKey(pos[0],pos[1]))){
                // 行动
                return pos1;
            }
        }

        // 是老虎和狮子时可跳过河道
        if(!(node.name.indexOf("_lion") == -1) || !(node.name.indexOf("_tiger") == -1)){
            // 将行进的方向有河流流时
            if(MapUtil.instance.mapRiver.has(MapUtil.instance.getKey(pos[0],pos[1]))){
                // 将行进路线无棋子时
                if(!MapUtil.instance.mapPieces.has(MapUtil.instance.getKey(pos_[0],pos_[1]))){
                    // 是否有老鼠
                    if(!this._checkRiverHasMouse(node,type)){
                        // 行动
                        return pos2;
                    }
                }
            }
        }

        // 其他棋子 将行动位置没有棋子时
        if(!MapUtil.instance.mapPieces.has(MapUtil.instance.getKey(pos[0],pos[1]))){
            // 将行动位置不是河流时
            if(!MapUtil.instance.mapRiver.has(MapUtil.instance.getKey(pos[0],pos[1]))){
                return pos1;
            }

        }

        return null;
    }

    /**
     * 将要行动 的坐标
     *
     * @param type 上下左右
     * @param x
     * @param y
     * @param index 0正常坐标 1穿越河道
     * @private
     */
    private _willMove(type:string,x:number,y:number,index:number){

        let x1 = x;
        let x2 = x;
        let y1 = y;
        let y2 = y;
        if(type=="up"){
            y1 = y1+148;
            y2 = y2+148*4;
        }
        if(type=="down"){
            y1 = y1-148;
            y2 = y2-148*4;
        }
        if(type=="left"){
            x1 = x1 -148;
            x2 = x2 -148*3;
        }
        if(type=="right"){
            x1 = x1 + 148;
            x2 = x2 + 148*3;
        }

        if(index==0){
            return [x1,y1];
        }else {
            return [x2,y2];
        }

        // return [x1,y1,x2,y2];
    }


    // 可以吃掉的
    private _showFight(node:Node){


        // 上
        let position = this._isNotFight("up",node);
        let att = node.getChildByName("att_up") as Node;
        if(position!=null){
            att.setPosition(position[0],position[1]);
            att.active = true;
        }else{
            att.active = false;
        }
        // 下
        position = this._isNotFight("down",node);
        att = node.getChildByName("att_down") as Node;
        if(position!=null){
            att.setPosition(position[0],position[1]);
            att.active = true;
        }else{
            att.active = false;
        }

        position = this._isNotFight("left",node);
        att = node.getChildByName("att_left") as Node;
        // 左
        if(position!=null){
            att.setPosition(position[0],position[1]);
            att.active = true;
        }else{
            att.active = false;
        }
        // 右
        position = this._isNotFight("right",node);
        att = node.getChildByName("att_right") as Node;
        if(position!=null){
            att.setPosition(position[0],position[1]);
            att.active = true;
        }else{
            att.active = false;
        }
    }

    // 是否可吃掉
    private _isNotFight(type:string,node:Node){
        let x = node.position.x;
        let y = node.position.y;

        // 节点坐标
        let pos = this._willMove(type,node.position.x,node.position.y,0);
        if(pos[0]<-518 || pos[0]>518){
            return null;
        }
        if(pos[1]<-666 || pos[1]>666){
            return null;
        }
        // 穿越河流坐标
        let pos_ = this._willMove(type,node.position.x,node.position.y,1);


        let pos1 = this._willMove(type,0,0,0);
        let pos2 = this._willMove(type,0,0,1);


        // 当前阵营
        let camp = node.name.substr(0,1);
        // 是否是陷阱
        let w = MapUtil.instance.mapTrap.has(MapUtil.instance.getKey(pos[0],pos[1]));
        // 如果是陷阱 并且陷阱里有棋子
        if(w && MapUtil.instance.mapPieces.has(MapUtil.instance.getKey(pos[0],pos[1]))){
            // 同阵营时
            let cnode = MapUtil.instance.mapPieces.get(MapUtil.instance.getKey(pos[0],pos[1]));
            if(camp == cnode.name.substr(0,1)){
                return null;
            }else{
                // 非同阵营时
                if("r" != camp  && pos[1]<0 && w){
                    return pos1;
                }
                if("b" != camp  && pos[1]>0 && w){
                    return pos1;
                }
            }

        }


        // 是老鼠时
        if(!(node.name.indexOf("_mouse") == -1)) {
            // 没有棋子时
            if (!MapUtil.instance.mapPieces.has(MapUtil.instance.getKey(pos[0],pos[1]))) {
                return null;
            }

            // 同阵营时
            let cnode = MapUtil.instance.mapPieces.get(MapUtil.instance.getKey(pos[0],pos[1]));
            if(node.name.substr(0,1) == cnode.name.substr(0,1)){
                return null;
            }

            // 一个在水里一个在陆地
            let o1 = MapUtil.instance.mapRiver.has(MapUtil.instance.getKey(x,y));
            let o2 = MapUtil.instance.mapRiver.has(MapUtil.instance.getKey(pos[0],pos[1]));
            if(o1 != o2){
                return null;
            }

            // 是否可吃掉
            if(this._checkPower(node.name,cnode.name)){
                // 行动
                return pos1;
            }
        }


        // 是老虎和狮子时可跳过河道
        if(!(node.name.indexOf("_lion") == -1) || !(node.name.indexOf("_tiger") == -1)){
            // 将行动位置是河流时
            if(MapUtil.instance.mapRiver.has(MapUtil.instance.getKey(pos[0],pos[1]))){
                // 有棋子时
                if (MapUtil.instance.mapPieces.has(MapUtil.instance.getKey(pos_[0], pos_[1]))) {
                    let cnode = MapUtil.instance.mapPieces.get(MapUtil.instance.getKey(pos_[0], pos_[1]));
                    // 同阵营推出
                    if(node.name.substr(0,1) == cnode.name.substr(0,1)){
                        return null;
                    }
                    // 有有老鼠时
                    if(this._checkRiverHasMouse(node,type)){
                        return null;
                    }
                    // 是否可吃掉
                    if(this._checkPower(node.name,cnode.name)){
                        // 行动
                        return pos2;
                    }
                }
            }else {
                // 不是河流
                // 并且有棋子时
                if (MapUtil.instance.mapPieces.has(MapUtil.instance.getKey(pos[0],pos[1]))) {
                    let cnode = MapUtil.instance.mapPieces.get(MapUtil.instance.getKey(pos[0],pos[1]));
                    // 同阵营推出
                    if(node.name.substr(0,1) == cnode.name.substr(0,1)){
                        return null;
                    }
                    // 是否可吃掉
                    if(this._checkPower(node.name,cnode.name)){
                        // 行动
                        return pos1;
                    }
                }

            }
        }


        // 将行动位置是河流时
        if(MapUtil.instance.mapRiver.has(MapUtil.instance.getKey(pos[0],pos[1]))){
            return null;
        }
        // 其他情况
        if(MapUtil.instance.mapPieces.has(MapUtil.instance.getKey(pos[0],pos[1]))) {
            // 将行进的目标
            let cnode = MapUtil.instance.mapPieces.get(MapUtil.instance.getKey(pos[0],pos[1]));
            //@ts-ignore
            if(this._checkPower(node.name,cnode.name)){
                // 行动
                return pos1;
            }
        }

        return null;

    }

    // 是否可以吃掉 name1待行动，name2敌对方
    private _checkPower(name1:string,name2:string):boolean{

        // 同阵营不能吃
        if(name1.substr(0,1) == name2.substr(0,1)){
            return false;
        }

        // 如果是老鼠 可以吃大象
        if(!(name1.indexOf("_mouse") == -1)){
            if(MapUtil.instance.mapObjPieces.get(name2).power == 7){
                return true;
            }
        }

        // 如果是大象不可以吃老鼠
        if(!(name1.indexOf("_elephant") == -1)){
            if(MapUtil.instance.mapObjPieces.get(name2).power == 0){
                return false;
            }
        }


        // 其他的正常吃
        if(MapUtil.instance.mapObjPieces.get(name1).power>=MapUtil.instance.mapObjPieces.get(name2).power){
            return true;
        }

        return false;

    }


    // 清空脚印
    public clearFootAndFight(){
        if(this._selectPiece == null){
            return;
        }

        this._selectPiece.getChildByName("up").active = false;
        this._selectPiece.getChildByName("down").active = false;
        this._selectPiece.getChildByName("left").active = false;
        this._selectPiece.getChildByName("right").active = false;

        this._selectPiece.getChildByName("att_up").active = false;
        this._selectPiece.getChildByName("att_down").active = false;
        this._selectPiece.getChildByName("att_left").active = false;
        this._selectPiece.getChildByName("att_right").active = false;

        // 隐藏脚印后 清空当前选中
        this._selectPiece = null;

    }


    /**
     * 点击移动
     */
    public onClickMove(event){
        this.clearFootAndFight();

        let node = event.target as Node;
        let p = node.parent;
        // 记录原始位置
        let oldPosX = p.position.x;
        let oldPosY = p.position.y;

        let worldPos = p.getComponent(UITransform).convertToWorldSpaceAR(node.position);
        let toPos = p.parent.getComponent(UITransform).convertToNodeSpaceAR(worldPos);


        let msg = {
            pos:{
                'from':{'x':p.position.x,'y':p.position.y},'to':{'x':toPos.x,'y':toPos.y}
            }
        }
        // 发送移动
        MgobeUtil.instance.sendToClient(msg);

        // 开始移动
        tween(p)
            .to(0.3, {position: toPos})
            .call(() => {

                // 删除原来的坐标
                MapUtil.instance.mapPieces.delete(MapUtil.instance.getKey(oldPosX,oldPosY));
                // 添加至新的坐标
                MapUtil.instance.mapPieces.set(MapUtil.instance.getKey(toPos.x,toPos.y),p);


                if(MapUtil.instance.mapBen.has(MapUtil.instance.getKey(toPos.x,toPos.y))){
                    ClientEvent.dispatchEvent(Constant.FIGHT_UI.ON_COUNT_DOWN_STOP);
                    alert("游戏结束");
                    return;
                }

                // 行动后变更回合
                this._changeRound(0);

                // 行动结束
                this._isAction = false;

            })
            .start();



    }


    /**
     * 点击吃掉
     */
    public onClickFight(event){
        this.clearFootAndFight();

        let node = event.target as Node;
        let p = node.parent;
        // 记录原始位置
        let oldPosX = p.position.x;
        let oldPosY = p.position.y;

        let worldPos = p.getComponent(UITransform).convertToWorldSpaceAR(node.position);
        let toPos = p.parent.getComponent(UITransform).convertToNodeSpaceAR(worldPos);

        let msg = {
            pos:{
                'from':{'x':p.position.x,'y':p.position.y},'to':{'x':toPos.x,'y':toPos.y}
            }
        }

        // 发送吃掉
        MgobeUtil.instance.sendToClient(msg);

        // 开始移动
        tween(p)
            .to(0.3, {position: toPos})
            .call(() => {
                // 移动结束后删除棋子

                // 获取到点击位置的棋子
                let oldKey = MapUtil.instance.getKey(toPos.x,toPos.y);
                let oldNode = MapUtil.instance.mapPieces.get(oldKey) as Node;
                oldNode.active = false;
                // 删除现有位置棋子
                MapUtil.instance.mapPieces.delete(oldKey);

                // 删除原来的坐标
                MapUtil.instance.mapPieces.delete(MapUtil.instance.getKey(oldPosX,oldPosY));
                // 添加至新的坐标
                MapUtil.instance.mapPieces.set(MapUtil.instance.getKey(toPos.x,toPos.y),p);


                // 行动后变更回合
                this._changeRound(0);


                // 行动结束
                this._isAction = false;
            })
            .start();


    }



    /**
     * 消息回调
     *
     * @param sendPlayerId
     * @param msg
     * @private
     */
    private _onRecvFromClient(sendPlayerId:string,msg:string){
        let obj = JSON.parse(msg);

        // 有坐标的为移动
        // @ts-ignore
        if(obj.pos){
            // @ts-ignore
            this._syncMove(obj.pos);
        }
        // 有消息 待开发
        // @ts-ignore
        if(obj.msg){

        }

        // 回合倒计时结束 更换 行动玩家
        if(obj.timeOut){
            // 行动后变更回合
            this._changeRound(1);
        }

    }


    /**
     * 同步移动
     *
     * @private
     */
    private _syncMove(obj){

        let fromNode:Node = MapUtil.instance.mapPieces.get(MapUtil.instance.getKey(obj.from.x,obj.from.y)) as Node;
        let toPos = new Vec3(obj.to.x,obj.to.y,fromNode.position.z);
        let toKey = MapUtil.instance.getKey(obj.to.x,obj.to.y);

        tween(fromNode)
            .to(0.3, {position: toPos})
            .call(() => {
                // 移动结束后删除棋子

                // 如果目标有棋子
                if(MapUtil.instance.mapPieces.has(toKey)){
                    // 获取到点击位置的棋子
                    let oldKey = MapUtil.instance.getKey(toPos.x,toPos.y);
                    let oldNode = MapUtil.instance.mapPieces.get(oldKey) as Node;
                    oldNode.active = false;
                    // 删除现有位置棋子
                    MapUtil.instance.mapPieces.delete(oldKey);
                }

                // 删除原来的坐标
                MapUtil.instance.mapPieces.delete(MapUtil.instance.getKey(obj.from.x,obj.from.y));
                // 添加至新的坐标
                MapUtil.instance.mapPieces.set(MapUtil.instance.getKey(toPos.x,toPos.y),fromNode);



                // 行动开始
                this._isAction = true;

                // 行动后变更回合
                this._changeRound(1);
            })
            .start();

    }

    /**
     * 变更回合
     *
     * @param index 0:local 1:callback
     * @private
     */
    private _changeRound(index:number){
        // 停止计时器
        ClientEvent.dispatchEvent(Constant.FIGHT_UI.ON_COUNT_DOWN_STOP);
        // 行动结束停止倒计时 并 开始对手的倒计时
        let players: Array<Player> = this.currentGameState.players;
        for (let i = 0; i <= 1; i++) {
            if (this._currentPlayerId === players[i].channel.openId) {

                if(index==0){
                    index = players[i].camp==0?1:0;
                }else{
                    index = players[i].camp;
                }
                ClientEvent.dispatchEvent(Constant.FIGHT_UI.ON_COUNT_DOWN_START,index,30);

            }
        }
    }

    // 超时
    private _sendTimeOut(camp:number){

        // 清空路径
        this.clearFootAndFight();

        // 变更回合 倒计时
        this._changeRound(0);


        log("***********",camp,this._camp);

        // 超时更换行动状态
        // this._isAction = !this._isAction;
        if(camp == this._camp){
            this._isAction = false;
        }
        // 对方回合超时 本地可行动
        if(camp != this._camp){
            this._isAction = true;
            return;
        }
        let msg = {
            timeOut:{}
        }

        // 发送时间超时
        MgobeUtil.instance.sendToClient(msg);

    }

}

/**
 * [1] Class member could be defined like this.
 * [2] Use `property` decorator if your want the member to be serializable.
 * [3] Your initialization goes here.
 * [4] Your update function goes here.
 *
 * Learn more about scripting: https://docs.cocos.com/creator/3.3/manual/zh/scripting/
 * Learn more about CCClass: https://docs.cocos.com/creator/3.3/manual/zh/scripting/ccclass.html
 * Learn more about life-cycle callbacks: https://docs.cocos.com/creator/3.3/manual/zh/scripting/life-cycle-callbacks.html
 */
